package net.esj.auth.inst.struts2.web;

import java.lang.reflect.Method;
import java.util.regex.Pattern;

import javax.servlet.http.HttpServletRequest;

import net.esj.basic.core.engine.annotation.Ignore;
import net.esj.basic.core.view.RequestUtils;
import net.esj.basic.core.view.ResponseStatusCode;
import net.esj.basic.pojo.op.Operator;
import net.esj.basic.pojo.system.UserRule;
import net.esj.basic.service.provider.UserRuleProvider;

import org.apache.commons.lang.StringUtils;
import org.apache.struts2.ServletActionContext;

import com.opensymphony.xwork2.ActionInvocation;
import com.opensymphony.xwork2.interceptor.AbstractInterceptor;

public class AdministratorAuthInterceptor extends
AbstractInterceptor implements ResponseStatusCode {

	/**
	 * 
	 */
	private static final long serialVersionUID = 2907238171372826148L;

	public static final String ACTION_NON_AUTHORITATIVE = "nonAuth";

	public static final String ACTION_OVER_AUTHORITATIVE = "overAuth";

	public static final String ACTION_METHOD_ANNOTATION_KEY = "auth";

	@Override
	public String intercept(ActionInvocation invocation) throws Exception {
		if(checkIgnore(invocation)){
			return invocation.invoke();
		}
		String uri = RequestUtils
				.getURIWithoutContextPath((HttpServletRequest) ServletActionContext
						.getRequest());
		boolean adminExists = false;
		for (UserRule rule : UserRuleProvider.allUserRules()) {
			Object o = UserRuleProvider.getSessionUser(ServletActionContext
					.getRequest().getSession(), rule.getUserClass());
			if (o instanceof Operator) {
				adminExists = true;
				if (((Operator) o).isAllowed(uri, ServletActionContext
						.getRequest().getParameterMap())) {
					invocation.getInvocationContext().put("operationSet", ((Operator)o).findOperations(uri, ServletActionContext
							.getRequest().getParameterMap()));
					return invocation.invoke();
				}
			}
		}
		//System.out.println(uri);
		if (adminExists) {
			ServletActionContext.getResponse().setStatus(
					RESPONSE_STATUS_OVER_AUTH);
			System.out.println("地址:["+uri+"],权限不存在");
			return ACTION_OVER_AUTHORITATIVE;
		} else {
			ServletActionContext.getResponse().setStatus(
					RESPONSE_STATUS_UNLOGIN_ERROR);
			return ACTION_NON_AUTHORITATIVE;
		}

		// if(StringUtils.equals(superAdmin,admin.getName())){//配置的超级管理员不受权限控制
		// arg2.doFilter(servletRequest, servletResponse);
		// return;
		// }
	}

	/**
	 * 检查是否包含忽略注解
	 * 如包含则自动跳过
	 * @param invocation
	 * @return
	 */
	protected boolean checkIgnore(ActionInvocation invocation){
		Object action = invocation.getAction();
		String methodName = invocation.getProxy().getMethod();
		try {
			Method method = action.getClass().getMethod(methodName);
			if(method!=null && method.isAnnotationPresent(Ignore.class)){
				Ignore ig = method.getAnnotation(Ignore.class);
				for(String str : ig.value()){
					if(StringUtils.equalsIgnoreCase(str, ACTION_METHOD_ANNOTATION_KEY)){
						return true;
					}
				}
			}
		} catch (SecurityException e) {
		} catch (NoSuchMethodException e) {
		}
		return false;
	}

	public static void main(String[] args) {
		System.out.println(Pattern.matches("/core/admin.html", "/core/admin"));
	}

}
